package com.aos.erp.common.lock;

import com.aos.erp.common.exception.BizException;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.lang.reflect.Method;

@Slf4j
@Aspect
@Configuration
public class AxLockMethodInterceptor {
    @Resource
    private AxLockService lockService;

    private AxLockKeyGenerator lockKeyGenerator = new LockKeyGenerator();

    @Around("execution(public * *(..)) && @annotation(com.aos.erp.common.lock.AxLock)")
    public Object interceptor(ProceedingJoinPoint pjp) throws Throwable {
        MethodSignature signature = (MethodSignature) pjp.getSignature();
        Method method = signature.getMethod();
        AxLock lock = method.getAnnotation(AxLock.class);
        if (StringUtils.isEmpty(lock.prefix())) {
            throw new RuntimeException("lock key can't be null...");
        }
        final String lockKey = lockKeyGenerator.getLockKey(pjp);
        String identifier = null;

        try {
            identifier = lockService.lockWithTimeout(lockKey, lock);
            if (identifier != null) {
                return pjp.proceed();
            } else {
                throw new BizException("服务器繁忙，请稍后再试");
            }
        } finally {
            if (identifier != null) {
                //如果演示的话需要注释该代码;实际应该放开
                lockService.releaseLock(lockKey, identifier);
            }
        }
    }
}